/*
 * HTProperties.cpp
 *
 *  Created on: Mar 14, 2009
 *      Author: Andrzej Olchawa
 *      mailto: andrzejolchawa@gmail.com
 *      http://www.hardtechnology.org
 *      This is a part of the Armazd project, which is covered by
 *      GNU GPL v2 license.
 */

#include "HTProperties.h"

HTProperties::HTProperties() {}

HTProperties::HTProperties(string filePath)
{
	propertiesFilePath = filePath;
	loadProperties();
}

HTProperties::~HTProperties(){}

void HTProperties::loadProperties(string filePath)
{
	propertiesFilePath = filePath;
	loadProperties();
}

void HTProperties::loadProperties()
{
	propertiesList.clear();
	numberOfElements = 0;

	if (propertiesFilePath.empty())
	{
		throw HTException("void AOFrameworks.AOProperties.loadProperties(): \
 						   properties file path is empty.");
	}

	ifstream file(propertiesFilePath.c_str(), std::ios::out);
	if (!file)
	{
		throw HTException("void AOFrameworks.AOProperties.loadProperties(): \
 						   can't open file "+ propertiesFilePath);
	}

	int lineIndex = 0;
	string stringLine;

	while (getline(file,stringLine))
	{
		lineIndex++;

		stringLine = HTStringUtilities::trim(stringLine);

		if (isCommentLine(stringLine) || stringLine.empty())
		{
			continue;
		}

		string key = "";
		string value = "";

		if (!extractKeyAndValueFromString(key, value, stringLine))
		{
			throw HTException("void AOFrameworks.AOProperties.loadProperties(): \
			 				   syntax error in " + propertiesFilePath + "("
			 				 + HTConverter::intToStr(lineIndex) + ")");
		}

		propertiesList[key] = value;
		numberOfElements++;
	}
}

bool HTProperties::extractKeyAndValueFromString(string &key, string &value,
		const string &str, const string &delimiter)
{
	int delimiterPosition = str.find_first_of(delimiter,0);

	if (delimiterPosition <= 0 ||
		delimiterPosition >= (int)str.length()-1)
	{
		return false;
	}

	key = HTStringUtilities::trim(str.substr(0, delimiterPosition));
	value = HTStringUtilities::trim(str.substr(delimiterPosition+1, str.length()));

	if ( HTStringUtilities::contains(key, delimiter) ||
		 HTStringUtilities::contains(value, delimiter) )
	{
		return false;
	}

	return true;
}

bool HTProperties::isCommentLine(const string &str, const string &commentType)
{
	if (str.empty())
	{
		return false;
	}

	string tmpString = HTStringUtilities::trim(str);
	if ( strstr(tmpString.c_str(), commentType.c_str()) == tmpString.c_str() )
	{
		return true;
	}
	else
	{
		return false;
	}
}

void HTProperties::printPropertiesList()
{
	MAP_OF_STRINGS::iterator mapIterator;

	for (mapIterator = propertiesList.begin();
		 mapIterator != propertiesList.end();
		 mapIterator++)
	{
		cout << mapIterator->first << " = " << mapIterator->second << endl;
	}
}

MAP_OF_STRINGS HTProperties::getPropertiesList()
{
	return propertiesList;
}

string HTProperties::operator[](const string key)
{
	return propertiesList[key];
}

HTPropertiesElement HTProperties::operator[](const int index)
{
	if (index >= (int)propertiesList.size())
	{
		throw HTException("string AOFramework.AOProperties.operator[](const int): \
						   propertiesList - out of range");
	}
	MAP_OF_STRINGS::iterator mapIterator = propertiesList.begin();

	int tmpIndex = 0;
	while (tmpIndex <= (int)propertiesList.size())
	{
		if (tmpIndex == index)
		{
			break;
		}
		tmpIndex++;
		mapIterator++;
	}
	HTPropertiesElement p;
	p.key = mapIterator->first;
	p.value = mapIterator->second;
	return p;
}

int HTProperties::getNumberOfElements()
{
	return numberOfElements;
}
